package xconfig

import (
	"io"
	"log"
	"os"
	"strconv"
	"strings"
)

// StringGetter .
type StringGetter interface {
	GetString(k string, dv ...any) string
}

// Putter .
type Putter interface {
	Put(k string, v any) error
}

type Merger interface {
	Merge(in io.Reader) error
}

// Unmarshaler .
type Unmarshaler interface{
  Unmarshal(key string, ptr any) error
}

// Config .
type Config interface {
	StringGetter
	Putter

	Merger
  Unmarshaler
}

// GetBool .
func GetBool(c Config, k string, dv ...any) bool {
	sv := c.GetString(k, dv...)
	sv = strings.ToLower(sv)
	// cast sv to Bool
	if sv == "true" || sv == "1" || sv == "y" {
		return true
	}
	return false
}

// GetInt .
func GetInt(c Config, k string, dv ...any) int {
	sv := c.GetString(k, dv...)
	sv = strings.ToLower(sv)
	n, err := strconv.Atoi(sv)
	if err != nil {
		log.Printf("config: GetInt from %s got error: %v", sv, err)
	}
	return n
}

// MergeFile .
func MergeFile(c Config, file string) error {
	in, err := os.Open(file)
	defer in.Close()
	if err != nil {
		return err
	}
	return c.Merge(in)
}

// MergeDir
func MergeDir(c Config, dir string) error{
  es,err:=os.ReadDir(dir)
  if err != nil {
    return err
  }
  // process dir files
  for _,e := range es {
    if e.IsDir(){
      continue
    }
    MergeFile(c, e.Name())
  }
  return nil
}

// Put os.Env to Config.
func PutEnv(c Config) {
	vs := os.Environ()
	for _, line := range vs {
		n := strings.Index(line, "=")
		if n < 1 {
			continue
		}
		k := strings.TrimSpace(line[0:n])
		v := strings.TrimSpace(line[n+1:])
		c.Put(k, v)
	}
}


// Get
func GetValue(c Config, prefix string, ptr any) error{

  return nil
}
